<template>
  <!-- 弹窗-组件(自定义) -->
  <el-dialog v-if="dialog" ref="dialog" v-el-drag-dialog class="c_dialog"
    :class="{def:!!overflow}"
    :custom-class="dialog.class" :sNe="spaceNe" :sAu="spaceAuto"
    :visible.sync="dialog.isOpen" :width="dialog.width" :title="dialog.title"
    :fullscreen="dialog.fullscreen" :top="dialog.top" :modal="dialog.modal"
    :modal-append-to-body="dialog.modalBody" :append-to-body="dialog.isBody"
    :close-on-click-modal="dialog.modalClose" :close-on-press-escape="dialog.escClose"
    :show-close="dialog.close" :center="dialog.center" :destroy-on-close="dialog.dataClose"
    @close="clearBtn" @open="openHandle"
  >
    <!-- 标题 -->
    <template #title><slot name="title" /></template>
    <!-- body -->
    <slot>
      <c-form v-if="form" ref="cForm" :form="form" :cols="cols" :rows="rows"
        :option="formOption" :item-option="formItem" @confirm="confirm">
        <!-- item整体-slot -->
        <template v-for="(item) in formItem" #[item.prop]="{row, $index}">
          <slot :name="item.prop" :row="row" :$index="$index" />
        </template>
        <!-- item外cols层-slot -->
        <template v-for="(item) in formItem" #[attrProp(item.prop,7)]="{row, $index}">
          <slot :name="'cols_'+item.prop" :row="row" :$index="$index" />
        </template>
        <!-- item内部 'item_' -slot -->
        <template v-for="(item) in formItem" #[attrProp(item.prop,0)]="{row, $index}">
          <slot :name="'item_'+item.prop" :row="row" :$index="$index" />
        </template>
        <!-- item-标签文本 'label_' -slot -->
        <template v-for="(item) in formItem" #[attrProp(item.prop,1)]="{row, $index}">
          <slot :name="'label_'+item.prop" :row="row" :$index="$index" />
        </template>
        <!-- item-校验信息 'error_' -slot -->
        <template v-for="(item) in formItem" #[attrProp(item.prop,2)]="{row, error, $index}">
          <slot :name="'error_'+item.prop" :row="row" :$index="$index" :error="error" />
        </template>
        <!-- input-输入框头部内容 'prefix_' -slot -->
        <template v-for="(item) in formItem" #[attrProp(item.prop,3)]><slot :name="'prefix_'+item.prop" /></template>
        <!-- input-输入框尾部内容 'suffix_' -slot -->
        <template v-for="(item) in formItem" #[attrProp(item.prop,4)]><slot :name="'suffix_'+item.prop" /></template>
        <!-- input-输入框前置内容 'prepend_' -slot -->
        <template v-for="(item) in formItem" #[attrProp(item.prop,5)]><slot :name="'prepend_'+item.prop" /></template>
        <!-- input-输入框后置内容 'append_' -slot -->
        <template v-for="(item) in formItem" #[attrProp(item.prop,6)]><slot :name="'append_'+item.prop" /></template>
        <!-- 在表单-末尾插入其他元素 -->
        <template #append><slot name="form_append" /></template>
        <!-- 在表单-末尾插入按钮 -->
        <template #button="{formRef}"><slot name="form_button" :formRef="formRef" /></template>
      </c-form>
    </slot>
    <!-- 追加内容 -->
    <slot name="append"></slot>
    <!-- 底部 -->
    <span v-if="!footerNe" slot="footer" class="dialog-footer">
      <slot name="footer">
        <el-button @click="clearBtn">取 消</el-button>
        <el-button type="primary" :loading="dialog.loading" @click="confirm()">{{ btnTxt||'确 定' }}</el-button>
      </slot>
    </span>
  </el-dialog>
</template>
<script>
import ui from 'element-ui'
import cForm from './form' // 表单
export default {
  name: 'cDialog',
  components: {
    ElDialog: ui.Dialog, cForm
  },
  filters: {

  },
  props: {
    dialog: Object, // 弹窗
    form: Object, // 表单
    formOption: Object, // 表单配置
    formItem: Array, // 表单-子项配置
    rows: Object, // 行 layout布局
    cols: Object, // 列 layout布局
    beforeClose: Function, // 关闭前回调
    footerNe: Boolean, // 是否取消尾部按钮
    spaceNe: Boolean, // 清除body间距
    spaceAuto: Boolean, // body间距10px
    overflow: { // body滚动
      type: [Boolean, String, Number],
      default: true
    },
    endHeight: String, // 弹窗底部高度
    btnTxt: String, // 确定按钮-文本
    lockHeight: Boolean // 锁定body高度
  },
  data() {
    return { isInit: false }
  },
  created() {
  },
  methods: {
    // init初始化
    init(domDialog) {
      // 处理-内容高度
      const { overflow: overH, endHeight, lockHeight } = this
      if (overH) {
        const children = domDialog.children
        const height = lockHeight ? 'height' : 'max-height'
        const typeVal = typeof overH
        switch (typeVal) {
          case 'string': // 字符串
            children[1].style[height] = overH
            break
          case 'number': // 数字
            children[1].style[height] = overH + 'px'
            break
          default: { // boolean
            this.$nextTick(_ => {
              const mtop = domDialog.style['margin-top']
              const mBottom = endHeight || mtop
              const header = children[0] ? children[0].offsetHeight : 0
              const footer = children[2] ? children[2].offsetHeight : 0
              const calcStr = `100vh - ${mtop} - ${mBottom} - ${header}px - ${footer}px`
              children[1].style[height] = `calc(${calcStr})`
            })
          }
        }
      }
    },
    // 取消
    clearBtn() {
      this.dialog.isOpen = false
      if (this.$refs.cForm) { // 清除表单
        this.resetFields()
      }
      if (this.dialog.closeHandle) {
        this.dialog.closeHandle()
        return
      }
      this.$emit('close')
    },
    // 打开窗口
    openHandle() {
      const domDialog = this.$refs.dialog.$el.querySelector('.el-dialog')
      domDialog.style.top = 0
      domDialog.style.left = 0
      domDialog.style.marginBottom = 0
      // if (!this.isInit) {
      //   this.init(domDialog)
      //   this.isInit = true
      // }
      this.init(domDialog)
      if (this.dialog.openHandle) {
        this.dialog.openHandle(domDialog)
        return
      }
      this.$emit('open', domDialog)
    },
    // 属性名拼接
    attrProp(key, type) {
      const arr = [
        'item_', 'label_', 'error_', 'prefix_', 'suffix_',
        'prepend_', 'append_', 'cols_'
      ]
      return arr[type] + key
    },
    // 提交
    confirm(formRefs) {
      if (!formRefs) {
        const cForm = this.$refs.cForm
        formRefs = cForm ? cForm.$refs.form : null
      }
      if (this.dialog.confirm) {
        this.dialog.confirm(formRefs)
        return
      }
      this.$emit('confirm', formRefs)
    },
    // 重置
    resetFields() {
      this.$refs.cForm.resetFields()
    },
    // 清除
    clearValidate(props) {
      this.$refs.cForm.clearValidate(props)
    },
    // 检验-字段
    validateField(props, callback) {
      this.$refs.cForm.validateField(props, callback)
    },
    // 整个表单验证
    validate(callback) {
      return this.$refs.cForm.validate(callback)
    }
  }
}
</script>
<style lang="scss" scoped>
@import '~@/styles/mixin';
// 样式
.c_dialog{
  &.def{
    ::v-deep .el-dialog .el-dialog__body{
      max-height: 60vh;
      overflow: auto;
      @include scrollBar;
    }
  }
  &[sne]::v-deep .el-dialog .el-dialog__body{
    padding: 0;
  }
  &[sau]::v-deep .el-dialog .el-dialog__body{
    padding: 10px;
  }
}
</style>
